import time

class TimeCounter:
    """计时器类，用于测量代码执行时间。
    
    该类提供了多种计时功能，包括开始/停止计时、计算经过时间、全局计时等。
    
    Attributes:
        start_time (float): 当前计时任务的开始时间戳。
        end_time (float): 当前计时任务的结束时间戳。
        global_start_time (float): 全局计时的开始时间戳。
        global_end_time (float): 全局计时的结束时间戳。
    """
    
    def __init__(self, is_log: bool = False):
        """初始化计时器。
        
        该方法初始化计时器的各个时间属性为 None，并验证时间测量的准确性。
        """
        self.start_time = None              # 记录开始时间
        self.end_time = None                # 记录结束时间  
        self.global_start_time = None       # 记录全局开始时间
        self.global_end_time = None         # 记录全局结束时间
        self.is_log = is_log                # 是否详细时间
        # 验证时间测量的准确性
        t1 = time.time()
        time.sleep(1)
        t2 = time.time()
        print(f"定时器实际睡眠时间：{t2 - t1:.6f}秒")  # 应接近1.000000
        
    def start(self):
        """启动计时器。
        
        该方法记录当前时间作为计时任务的开始时间。
        """
        self.start_time = time.time()

    def stop(self):
        """停止计时器。
        
        该方法记录当前时间作为计时任务的结束时间。
        """
        self.end_time = time.time()

    def elapsed(self) -> float:
        """计算并返回经过的时间。
        
        该方法计算从开始时间到结束时间经过的时间（毫秒）。
        
        Returns:
            float: 经过的时间（毫秒）。
            
        Raises:
            ValueError: 如果计时器尚未启动或停止。
        """
        if self.start_time is None or self.end_time is None:
            raise ValueError("计时器尚未启动或停止。")
        return (self.end_time - self.start_time) * 1000  # 转换为毫秒

    def reset(self):
        """重置计时器。
        
        该方法重置计时器的开始时间，并将结束时间设为 None。
        """
        self.start_time = time.time()
        self.end_time = None

    def show_time(self, task_name: str = "Task"):
        """显示经过的时间。
        
        该方法计算并打印从开始时间到结束时间经过的时间。
        
        Args:
            task_name (str): 任务名称，用于输出显示。
        """
        elapsed_time = self.elapsed()
        if self.is_log is True:
            print(f"{task_name} took {elapsed_time:.4f} ms")

    def get_time_from_start(self, task_name: str = "Task"):
        """从开始时间计算经过的时间并显示。
        
        该方法计算从开始时间到当前时间经过的时间并打印。
        
        Args:
            task_name (str): 任务名称，用于输出显示。
            
        Raises:
            ValueError: 如果计时器尚未启动。
        """
        if self.start_time is None:
            raise ValueError("计时器尚未启动。")
        elapsed_time = (time.time() - self.start_time) * 1000  # 转换为毫秒
        if self.is_log is True:
            print(f"{task_name} took {elapsed_time:.4f} ms")

    def get_time_from_start_and_reset(self, task_name: str = "Task"):
        """从开始时间计算经过的时间，显示并重置开始时间。
        
        该方法计算从开始时间到当前时间经过的时间，打印结果，并重置开始时间。
        
        Args:
            task_name (str): 任务名称，用于输出显示。
            
        Returns:
            float: 经过的时间（毫秒）。
            
        Raises:
            ValueError: 如果计时器尚未启动。
        """
        if self.start_time is None:
            raise ValueError("计时器尚未启动。")
        elapsed_time = (time.time() - self.start_time) * 1000  # 转换为毫秒
        self.start_time = time.time()
        if self.is_log is True:
            print(f"{task_name} took {elapsed_time:.4f} ms")
        return elapsed_time

    def global_start(self):
        """启动全局计时器。
        
        该方法记录当前时间作为全局计时的开始时间，并打印启动信息。
        """
        self.global_start_time = time.time()
        if self.is_log is True:
            print("===============Global timer started==================")

    def global_stop(self, task_name: str = "Total") -> float:
        """停止全局计时器并显示总时间。
        
        该方法记录当前时间作为全局计时的结束时间，计算并打印总时间。
        
        Args:
            task_name (str): 任务名称，用于输出显示。
            
        Returns:
            float: 经过的时间（秒）。
            
        Raises:
            ValueError: 如果全局计时器尚未启动。
        """
        self.global_end_time = time.time()
        if self.global_start_time is None:
            raise ValueError("Global timer has not been started.")
        total_elapsed = (self.global_end_time - self.global_start_time) * 1000  # 转换为毫秒
        return_time = self.global_end_time - self.global_start_time
        if self.is_log is True:
            print(f"{task_name} took {total_elapsed:.4f} ms")
            print("===============Global timer stopped==================")
        self.global_start_time = None
        self.global_end_time = None
        return return_time